package com.hyt.it.ogt.kq.service.gov.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hyt.core.base.BaseEntity;
import com.hyt.core.base.BaseServiceImpl;
import com.hyt.it.ogt.kq.service.gov.api.ks.model.QueryUserRoomParam;
import com.hyt.it.ogt.kq.service.gov.api.ks.model.QueryUserTimeParam;
import com.hyt.it.ogt.kq.service.gov.api.ks.model.UserRoomVO;
import com.hyt.it.ogt.kq.service.gov.api.ks.model.UserTimeVO;
import com.hyt.it.ogt.kq.common.gov.constant.CodeEnum;
import com.hyt.it.ogt.kq.common.gov.constant.ResponseCode;
import com.hyt.it.ogt.kq.common.gov.constant.UserRoleType;
import com.hyt.it.ogt.kq.common.config.exception.KqException;
import com.hyt.it.ogt.kq.service.gov.mapper.TimeRoomExaminerMapper;
import com.hyt.it.ogt.kq.service.gov.model.entity.Time;
import com.hyt.it.ogt.kq.service.gov.model.entity.TimeRoomExaminer;
import com.hyt.it.ogt.kq.service.gov.model.vo.Tree;
import com.hyt.it.ogt.kq.service.gov.model.vo.examiner.TimeRoomExaminerVO;
import com.hyt.it.ogt.kq.service.gov.service.ITimeRoomExaminerService;
import com.hyt.it.ogt.kq.service.gov.service.ITimeService;
import com.hyt.it.ogt.kq.service.gov.service.TimeRoomExaminerCacheService;
import com.hyt.it.ogt.kq.common.gov.utils.DateTimeUtil;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 考务人员场次表 服务实现类
 * </p>
 *
 * @author wangg
 * @since 2021-11-25
 */
@Service
public class TimeRoomExaminerServiceImpl extends BaseServiceImpl<TimeRoomExaminerMapper, TimeRoomExaminer> implements ITimeRoomExaminerService {

    @Resource
    private TimeRoomExaminerCacheService timeRoomExaminerCacheService;
    @Resource
    private ITimeService iTimeService;

    @Override
    public List<UserRoomVO> getUserRoom(QueryUserRoomParam queryUserRoomParam) {

        String userType = queryUserRoomParam.getUserType();
        Time time =  iTimeService.getById(queryUserRoomParam.getTimeId());
        if(null == time) {
            return null;
        }
        String taskId = time.getTaskId();
        List<UserRoomVO> userRoomVOS = null;
        if (UserRoleType.USER_ROLE_TYPE_ADMIN.getCode().equals(userType)) {
            //管理员
            userRoomVOS = timeRoomExaminerCacheService.getUserRoomByAdminFromCache(queryUserRoomParam.getTimeId(), taskId);
        } else if (UserRoleType.USER_ROLE_TYPE_PROCTOR.getCode().equals(userType)) {
            userRoomVOS = timeRoomExaminerCacheService.getUserRoomByProctorFromCache(queryUserRoomParam.getTimeId(), taskId, queryUserRoomParam.getUserId());
        } else {
            throw new KqException(ResponseCode.ERROR_KS_USER_TYPE_NONE.getCode(),
                    ResponseCode.ERROR_KS_USER_TYPE_NONE.getMsg());
        }

        return userRoomVOS;
    }

    @Override
    public List<UserTimeVO> getUserTime(QueryUserTimeParam queryUserTimeParam) {
        String userType = queryUserTimeParam.getUserType();
        List<UserTimeVO> userTimeVOS = null;
        if (UserRoleType.USER_ROLE_TYPE_ADMIN.getCode().equals(userType)) {
            //管理员
            userTimeVOS = baseMapper.selectUserTimeByAdmin(queryUserTimeParam.getTaskId());
        } else if (UserRoleType.USER_ROLE_TYPE_PROCTOR.getCode().equals(userType)) {
            //监考员
            userTimeVOS = timeRoomExaminerCacheService.getUserTimeByProctorFromCache(queryUserTimeParam.getTaskId(),queryUserTimeParam.getUserId());
        } else {
            throw new KqException(ResponseCode.ERROR_KS_USER_TYPE_NONE.getCode(),
                    ResponseCode.ERROR_KS_USER_TYPE_NONE.getMsg());
        }

        if (userTimeVOS == null || userTimeVOS.isEmpty()) {
            return userTimeVOS;
        }

        //设置状态，和排序号
        userTimeVOS.stream().forEach(userTimeVO -> {
            LocalDateTime now = DateTimeUtil.getFormatNow();

            if (now.isBefore(userTimeVO.getStartTime())) {
                //未开考
                userTimeVO.setTimeState(CodeEnum.EXAM_TIME_STATE_NONE.getCode())
                        .setSort(2);
            } else if (now.isAfter(userTimeVO.getEndTime())) {
                //已结束
                userTimeVO.setTimeState(CodeEnum.EXAM_TIME_STATE_OVER.getCode())
                        .setSort(3);
            } else {
                //考中
                userTimeVO.setTimeState(CodeEnum.EXAM_TIME_STATE_ING.getCode())
                        .setSort(1);
            }

        });

        //排序
        userTimeVOS = userTimeVOS.stream().sorted(Comparator.comparing(UserTimeVO::getSort))
                .collect(Collectors.toList());

        return userTimeVOS;
    }

    @Override
    public void deleteAllocatedByTimeId(String taskId, String timeId) {
        QueryWrapper<TimeRoomExaminer> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(TimeRoomExaminer::getTaskId, taskId)
                .eq(TimeRoomExaminer::getTimeId, timeId);
        remove(queryWrapper);
        timeRoomExaminerCacheService.clearUserProctorCache(timeId,taskId);
    }

    @Override
    public void insertByBatchByTimeId(List<TimeRoomExaminer> timeRoomExaminerList){
       saveBatch(timeRoomExaminerList);
       if(!CollectionUtils.isEmpty(timeRoomExaminerList)){
           timeRoomExaminerCacheService.clearUserProctorCache(timeRoomExaminerList.get(0).getTimeId(),
                   timeRoomExaminerList.get(0).getTaskId());
       }
    }

    @Override
    public void deleteAllByUserId(TimeRoomExaminerVO timeRoomExaminerVO) {
        QueryWrapper<TimeRoomExaminer> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(TimeRoomExaminer::getTaskId, timeRoomExaminerVO.getTaskId())
                .eq(TimeRoomExaminer::getTimeId, timeRoomExaminerVO.getTimeId())
                .eq(TimeRoomExaminer::getUserId, timeRoomExaminerVO.getUserId());
        remove(queryWrapper);
        timeRoomExaminerCacheService.clearUserProctorCache(timeRoomExaminerVO.getTimeId(),timeRoomExaminerVO.getTaskId());
    }

    @Override
    public void deleteByTask(String taskId) {
        QueryWrapper<TimeRoomExaminer> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(TimeRoomExaminer::getTaskId, taskId);
        remove(queryWrapper);
        timeRoomExaminerCacheService.clearUserProctorCache(null,taskId);
    }

    @Override
    public boolean hasArranged(String taskId) {
        return this.lambdaQuery().eq(TimeRoomExaminer::getTaskId, taskId).eq(BaseEntity::getDelFlag, false).count() > 0;
    }

    @Override
    public List<Tree> buildTree(List<UserRoomVO> list) {
            List<Tree> treeList = new ArrayList<>();
            //先构造考点
            for(int i = 0 ; i < list.size(); i++){
                Tree tree = new Tree();
                tree.setId(list.get(i).getPlaceCode());
                tree.setText(list.get(i).getPlaceName());
                if(StrUtil.isNotBlank(list.get(i).getPlaceCode())){
                    if(CollectionUtil.isEmpty(treeList)){
                        treeList.add(tree);
                    }else{
                        boolean flag = true;
                        for(int k = 0; k < treeList.size(); k++){
                            if(treeList.get(k).getId().equals(list.get(i).getPlaceCode())){
                                flag = false;
                                break;
                            }
                        }
                        if(flag){
                            treeList.add(tree);
                        }
                    }
                }
            }
            //旧数据存在考点为空的情况
            if(CollectionUtil.isEmpty(treeList)){
                list.stream().forEach(e ->{
                    Tree tree = new Tree();
                    tree.setId(e.getRoomId());
                    tree.setText(e.getRoomName());
                    treeList.add(tree);
                });
            } else {
                treeList.stream().forEach(c -> {
                    List<Tree> childList = new ArrayList<>();
                    list.stream().filter(d -> d.getPlaceCode().equals(c.getId())).forEach(e ->{
                        Tree tree = new Tree();
                        tree.setId(e.getRoomId());
                        tree.setText(e.getRoomName());
                        tree.setPid(c.getId());
                        childList.add(tree);
                    });
                    c.setChildren(childList);
                });
            }
            return treeList;
    }
}
